package com.taotao.common.auth;

import com.alibaba.fastjson.JSON;
import com.taotao.common.RespData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 权限的拦截器
 *
 * @author: Fan Beibei
 * @date: 2018/5/4 17:56
 * @Modified By:
 */
@Slf4j
public abstract class AuthHandlerInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {//拦截controller方法
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        AuthRequired authRequired = handlerMethod.getBeanType().getAnnotation(AuthRequired.class);
        if (null == authRequired) {
            authRequired = handlerMethod.getMethodAnnotation(AuthRequired.class);
        }

        if (null == authRequired) {
            return true;
        }


        boolean result = validLoginRequired(request, response, authRequired);

        if (!result) {
            respLoginRequiredJson(response);
            return false;
        }

        String funcCode = authRequired.authCode();

        Long userId = getUserId(request);

        result = validFuncAccess(funcCode, userId);

        return result;

    }


    /**
     * 向前端返回需要登录访问
     *
     * @param response
     */
    public static void respLoginRequiredJson(HttpServletResponse response) throws IOException {
        try {
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().print(JSON.toJSONString(RespData.reLoginResp()));
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }

    }

    /**
     * 验证用户是否有权限访问controller方法，不需要此功能则直接返回true即可
     *
     * @param funcCode
     * @param userId
     * @return
     */
    protected abstract boolean validFuncAccess(String funcCode, Long userId);

    /**
     * 获取用户ID
     *
     * @param request
     * @return
     */
    protected abstract Long getUserId(HttpServletRequest request);


    /**
     * 验证是否登录
     *
     * @param request
     * @param response
     * @param authRequired
     * @return
     */
    protected abstract boolean validLoginRequired(HttpServletRequest request, HttpServletResponse response, AuthRequired authRequired);

}
